<template>
  <div class="firewall-rule-generator">


    <!-- 主要工作区域 -->
    <div class="main-workspace">
      <div class="workspace-grid">
        <!-- 左侧配置区域 -->
        <div class="workspace-card input-card">
          <div class="card-header">
            <div class="card-title">
              <div class="title-icon">
                <svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                  <path d="M12 20H21" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                  <path d="M16.5 3.5C16.8978 3.10217 17.4374 2.87868 18 2.87868C18.5626 2.87868 19.1022 3.10217 19.5 3.5C19.8978 3.89782 20.1213 4.43739 20.1213 5C20.1213 5.56261 19.8978 6.10217 19.5 6.5L10 16L6 17L7 13L16.5 3.5Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                </svg>
              </div>
              <div class="title-text">
                <h3>规则配置</h3>
                <p>配置防火墙规则参数</p>
              </div>
            </div>
            <div class="card-actions">
              <n-button @click="clearAll" size="small" class="clear-btn">
                <template #icon>
                  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                    <path d="M3 6H5H21" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                    <path d="M8 6V4C8 3.46957 8.21071 2.96086 8.58579 2.58579C8.96086 2.21071 9.46957 2 10 2H14C14.5304 2 15.0391 2.21071 15.4142 2.58579C15.7893 2.96086 16 3.46957 16 4V6M19 6V20C19 20.5304 18.7893 21.0391 18.4142 21.4142C18.0391 21.7893 17.5304 22 17 22H7C6.46957 22 5.96086 21.7893 5.58579 21.4142C5.21071 21.0391 5 20.5304 5 20V6H19Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                  </svg>
                </template>
                清空
              </n-button>
            </div>
          </div>
          
          <div class="card-content">
            <!-- 生成选项 -->
            <div class="config-section">
              <div class="section-header">
                <h4 class="section-title">生成选项</h4>
                <div class="info-badge">⚙️ 设置</div>
              </div>
              <div class="options-row">
                <div class="option-item">
                  <label class="option-label">输出格式</label>
                  <n-select v-model:value="config.outputFormat" :options="outputFormatOptions" size="small" />
                </div>
                <div class="option-item">
                  <label class="option-label">包含注释</label>
                  <n-switch v-model:value="config.includeComments" size="small" />
                </div>
              </div>
            </div>

            <!-- 基本配置 -->
            <div class="config-section">
              <div class="section-header">
                <h4 class="section-title">基本配置</h4>
                <div class="info-badge">ℹ️ 基础</div>
              </div>
              <div class="info-tip">
                <strong>基础设置</strong>：定义防火墙规则的基本行为，通常使用默认值即可
              </div>
              <div class="config-grid">
                <n-form-item label="规则动作">
                  <n-select v-model:value="config.action" :options="actionOptions" />
                  <template #feedback>
                    <span class="field-hint">ACCEPT允许通过，DROP丢弃，REJECT拒绝并回复</span>
                  </template>
                </n-form-item>
                <n-form-item label="协议">
                  <n-select v-model:value="config.protocol" :options="protocolOptions" />
                  <template #feedback>
                    <span class="field-hint">选择网络协议类型</span>
                  </template>
                </n-form-item>
                <n-form-item label="链">
                  <n-select v-model:value="config.chain" :options="chainOptions" />
                  <template #feedback>
                    <span class="field-hint">INPUT处理入站流量，OUTPUT处理出站流量</span>
                  </template>
                </n-form-item>
                <n-form-item label="插入位置">
                  <n-select v-model:value="config.insertPosition" :options="insertPositionOptions" />
                  <template #feedback>
                    <span class="field-hint">-I插入到开头，-A追加到末尾</span>
                  </template>
                </n-form-item>
              </div>
            </div>

            <!-- 源地址配置 -->
            <div class="config-section">
              <div class="section-header">
                <h4 class="section-title">源地址配置</h4>
                <div class="warning-badge">⚠️ 重要</div>
              </div>
              <div class="warning-tip">
                <strong>源地址</strong>：指发起连接的客户端IP地址，即"从哪里来"
              </div>
              <n-form-item label="源IP地址（每行一个，支持CIDR和IP范围，any、0.0.0.0/0、留空表示任意）" :validation-status="validationErrors.sourceIPs.length > 0 ? 'error' : undefined">
                <n-input
                  v-model:value="config.sourceIPs"
                  type="textarea"
                  :rows="4"
                  placeholder="192.168.1.1
192.168.1.0/24
192.168.1.1-192.168.1.10
any"
                />
                <template #feedback>
                  <div v-if="validationErrors.sourceIPs.length > 0" class="validation-errors">
                    <div v-for="error in validationErrors.sourceIPs" :key="error" class="error-item">
                      <span class="error-icon">⚠️</span>
                      <span class="error-text">{{ error }}</span>
                    </div>
                  </div>
                </template>
              </n-form-item>
            </div>

            <!-- 目标地址配置 -->
            <div class="config-section">
              <div class="section-header">
                <h4 class="section-title">目标地址配置</h4>
                <div class="warning-badge">⚠️ 重要</div>
              </div>
              <div class="warning-tip">
                <strong>目标地址</strong>：指连接的目标服务器IP地址，即"到哪里去"
              </div>
              <n-form-item label="目标IP地址（每行一个，支持CIDR和IP范围，any、0.0.0.0/0、留空表示任意）" :validation-status="validationErrors.destinationIPs.length > 0 ? 'error' : undefined">
                <n-input
                  v-model:value="config.destinationIPs"
                  type="textarea"
                  :rows="4"
                  placeholder="192.168.1.100
192.168.1.0/24
192.168.1.1-192.168.1.10
any"
                />
                <template #feedback>
                  <div v-if="validationErrors.destinationIPs.length > 0" class="validation-errors">
                    <div v-for="error in validationErrors.destinationIPs" :key="error" class="error-item">
                      <span class="error-icon">⚠️</span>
                      <span class="error-text">{{ error }}</span>
                    </div>
                  </div>
                </template>
              </n-form-item>
            </div>

            <!-- 端口/ICMP配置 -->
            <div class="config-section">
              <div class="section-header">
                <h4 class="section-title">{{ config.protocol === 'icmp' ? 'ICMP配置' : '端口配置' }}</h4>
                <div class="warning-badge">⚠️ 重要</div>
              </div>
              <div class="warning-tip">
                <strong>{{ config.protocol === 'icmp' ? 'ICMP类型' : '端口' }}</strong>：
                <span v-if="config.protocol === 'icmp'">选择ICMP消息类型（如ping请求、回复等）</span>
                <span v-else>源端口指客户端端口，目标端口指服务器端口</span>
              </div>
              
              <!-- ICMP类型配置 -->
              <div v-if="config.protocol === 'icmp'" class="config-grid">
                <n-form-item label="ICMP类型">
                  <n-select v-model:value="config.icmpType" :options="icmpTypeOptions" placeholder="选择ICMP类型" />
                </n-form-item>
              </div>
              
                              <!-- TCP/UDP端口配置 -->
                <div v-else-if="config.protocol === 'tcp' || config.protocol === 'udp'" class="config-grid">
                  <n-form-item label="源端口（any、all、留空表示任意端口）" :validation-status="validationErrors.sourcePorts.length > 0 ? 'error' : undefined">
                    <n-input
                      v-model:value="config.sourcePorts"
                      placeholder="80,443 或 80-90 或 any"
                    />
                    <template #feedback>
                      <div v-if="validationErrors.sourcePorts.length > 0" class="validation-errors">
                        <div v-for="error in validationErrors.sourcePorts" :key="error" class="error-item">
                          <span class="error-icon">⚠️</span>
                          <span class="error-text">{{ error }}</span>
                        </div>
                      </div>
                    </template>
                  </n-form-item>
                  <n-form-item label="目标端口（any、all、留空表示任意端口）" :validation-status="validationErrors.destinationPorts.length > 0 ? 'error' : undefined">
                    <n-input
                      v-model:value="config.destinationPorts"
                      placeholder="80,443 或 80-90 或 any"
                    />
                    <template #feedback>
                      <div v-if="validationErrors.destinationPorts.length > 0" class="validation-errors">
                        <div v-for="error in validationErrors.destinationPorts" :key="error" class="error-item">
                          <span class="error-icon">⚠️</span>
                          <span class="error-text">{{ error }}</span>
                        </div>
                      </div>
                    </template>
                  </n-form-item>
                </div>
              
              <!-- 其他协议不显示端口配置 -->
              <div v-else class="config-grid">
                <n-form-item>
                  <n-text depth="3">当前协议不需要端口配置</n-text>
                </n-form-item>
              </div>
            </div>

            <!-- 其他配置 -->
            <div class="config-section">
              <div class="section-header">
                <h4 class="section-title">其他配置</h4>
                <div class="info-badge">ℹ️ 高级</div>
              </div>
              <div class="info-tip">
                <strong>高级选项</strong>：这些配置通常使用默认值即可，仅在特殊场景下需要调整
              </div>
              <div class="config-grid">
                <n-form-item label="网络接口">
                  <n-input
                    v-model:value="config.interface"
                    placeholder="eth0"
                  />
                  <template #feedback>
                    <span class="field-hint">指定网络接口名称，留空表示所有接口</span>
                  </template>
                </n-form-item>
                <n-form-item label="状态匹配">
                  <n-select v-model:value="config.state" :options="stateOptions" />
                  <template #feedback>
                    <span class="field-hint">匹配连接状态，如新建连接、已建立连接等</span>
                  </template>
                </n-form-item>
              </div>
            </div>

          </div>
        </div>

        <!-- 右侧结果区域 -->
        <div class="workspace-card output-card">
          <div class="card-header">
            <div class="card-title">
              <div class="title-icon">
                <svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                  <path d="M9 12L11 14L15 10" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                  <path d="M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z" stroke="currentColor" stroke-width="2"/>
                </svg>
              </div>
              <div class="title-text">
                <h3>生成的规则</h3>
                <p>根据配置生成的防火墙规则</p>
              </div>
            </div>
            <div class="card-actions">
              <n-button 
                v-if="generatedRules" 
                @click="copyResult" 
                size="small" 
                type="primary"
              >
                <template #icon>
                  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                    <path d="M16 4H18C19.1046 4 20 4.89543 20 6V18C20 19.1046 19.1046 20 18 20H6C4.89543 20 4 19.1046 4 18V16" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                    <path d="M15 2H9C7.89543 2 7 2.89543 7 4V14C7 15.1046 7.89543 16 9 16H15C16.1046 16 17 15.1046 17 14V4C17 2.89543 16.1046 2 15 2Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                  </svg>
                </template>
                复制
              </n-button>
              <n-button 
                v-if="generatedRules" 
                @click="downloadResult" 
                size="small" 
                type="info"
              >
                <template #icon>
                  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                    <path d="M21 15V19C21 19.5304 20.7893 20.0391 20.4142 20.4142C20.0391 20.7893 19.5304 21 19 21H5C4.46957 21 3.96086 20.7893 3.58579 20.4142C3.21071 20.0391 3 19.5304 3 19V15" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                    <path d="M7 10L12 15L17 10" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                    <path d="M12 15V3" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                  </svg>
                </template>
                下载
              </n-button>
            </div>
          </div>
          
          <div class="card-content">
            <!-- 规则统计信息 -->
            <div v-if="generatedRules" class="rules-stats">
              <div class="stat-item">
                <span class="stat-label">规则数量:</span>
                <span class="stat-value">{{ ruleCount }}</span>
              </div>
              <div class="stat-item">
                <span class="stat-label">输出格式:</span>
                <span class="stat-value">{{ config.outputFormat }}</span>
              </div>
              <div class="stat-item">
                <span class="stat-label">字符数:</span>
                <span class="stat-value">{{ generatedRules.length }}</span>
              </div>
            </div>
            
            <!-- 生成的规则 -->
            <div class="rules-output-section">
              <div class="section-header">
                <h5 class="output-title">生成的防火墙规则</h5>
                <div class="output-badge">{{ config.outputFormat === 'both' ? 'iptables + firewalld' : config.outputFormat }}</div>
              </div>
              <n-input
                v-model:value="generatedRules"
                type="textarea"
                :rows="16"
                placeholder="配置参数后将在这里显示生成的防火墙规则..."
                readonly
                class="config-output"
              />
            </div>
            
            <!-- 使用说明 -->
            <div v-if="!generatedRules" class="usage-guide">
              <h5 class="guide-title">使用说明</h5>
              <div class="guide-content">
                <div class="guide-step">
                  <span class="step-number">1</span>
                  <span class="step-text">选择输出格式（iptables/firewalld）</span>
                </div>
                <div class="guide-step">
                  <span class="step-number">2</span>
                  <span class="step-text">配置左侧的防火墙规则参数</span>
                </div>
                <div class="guide-step">
                  <span class="step-number">3</span>
                  <span class="step-text">查看右侧生成的规则并复制使用</span>
                </div>
              </div>
            </div>
            
            <!-- 常见示例 -->
            <div class="examples-section">
              <h5 class="examples-title">常见配置示例</h5>
              <div class="examples-grid">
                <div class="example-card" @click="loadExample('web-server')">
                  <div class="example-icon">🌐</div>
                  <div class="example-content">
                    <h6>Web服务器</h6>
                    <p>开放HTTP/HTTPS端口</p>
                  </div>
                </div>
                <div class="example-card" @click="loadExample('ssh-access')">
                  <div class="example-icon">🔐</div>
                  <div class="example-content">
                    <h6>SSH访问</h6>
                    <p>限制SSH访问IP</p>
                  </div>
                </div>
                <div class="example-card" @click="loadExample('database')">
                  <div class="example-icon">🗄️</div>
                  <div class="example-content">
                    <h6>数据库</h6>
                    <p>数据库端口访问</p>
                  </div>
                </div>
                <div class="example-card" @click="loadExample('ping')">
                  <div class="example-icon">📡</div>
                  <div class="example-content">
                    <h6>Ping测试</h6>
                    <p>ICMP协议配置</p>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue';
import { useCopy } from '@/composable/copy';

const { copy } = useCopy();

// 配置状态
const config = ref({
  action: 'ACCEPT',
  protocol: 'tcp',
  chain: 'INPUT',
  insertPosition: 'I',
  sourceIPs: '',
  destinationIPs: '',
  sourcePorts: '',
  destinationPorts: '',
  icmpType: '',
  interface: '',
  state: '',
  outputFormat: 'iptables',
  includeComments: true
});

// 验证错误状态
const validationErrors = ref({
  sourceIPs: [] as string[],
  destinationIPs: [] as string[],
  sourcePorts: [] as string[],
  destinationPorts: [] as string[]
});

// 选项配置
const actionOptions = [
  { label: '允许 (ACCEPT)', value: 'ACCEPT' },
  { label: '拒绝 (DROP)', value: 'DROP' },
  { label: '拒绝并回复 (REJECT)', value: 'REJECT' },
  { label: '记录 (LOG)', value: 'LOG' }
];

const protocolOptions = [
  { label: 'TCP', value: 'tcp' },
  { label: 'UDP', value: 'udp' },
  { label: 'ICMP', value: 'icmp' },
  { label: '所有协议', value: 'all' }
];

const chainOptions = [
  { label: 'INPUT', value: 'INPUT' },
  { label: 'OUTPUT', value: 'OUTPUT' },
  { label: 'FORWARD', value: 'FORWARD' },
  { label: 'PREROUTING', value: 'PREROUTING' },
  { label: 'POSTROUTING', value: 'POSTROUTING' }
];

const insertPositionOptions = [
  { label: '插入到开头 (-I)', value: 'I' },
  { label: '追加到末尾 (-A)', value: 'A' }
];

const stateOptions = [
  { label: '无', value: '' },
  { label: '新建连接 (NEW)', value: 'NEW' },
  { label: '已建立连接 (ESTABLISHED)', value: 'ESTABLISHED' },
  { label: '相关连接 (RELATED)', value: 'RELATED' },
  { label: '无效连接 (INVALID)', value: 'INVALID' }
];

const outputFormatOptions = [
  { label: 'iptables', value: 'iptables' },
  { label: 'firewalld', value: 'firewalld' },
  { label: '两者都生成', value: 'both' }
];

// ICMP类型选项
const icmpTypeOptions = [
  { label: 'echo-request (ping请求)', value: 'echo-request' },
  { label: 'echo-reply (ping回复)', value: 'echo-reply' },
  { label: 'destination-unreachable (目标不可达)', value: 'destination-unreachable' },
  { label: 'source-quench (源站抑制)', value: 'source-quench' },
  { label: 'redirect (重定向)', value: 'redirect' },
  { label: 'time-exceeded (超时)', value: 'time-exceeded' },
  { label: 'parameter-problem (参数问题)', value: 'parameter-problem' },
  { label: 'timestamp-request (时间戳请求)', value: 'timestamp-request' },
  { label: 'timestamp-reply (时间戳回复)', value: 'timestamp-reply' },
  { label: 'info-request (信息请求)', value: 'info-request' },
  { label: 'info-reply (信息回复)', value: 'info-reply' }
];

// 生成的规则
const generatedRules = computed(() => {
  // 检查是否有验证错误
  const hasErrors = Object.values(validationErrors.value).some(errors => errors.length > 0);
  if (hasErrors) {
    return '';
  }
  
  if (!config.value.sourceIPs.trim() && !config.value.destinationIPs.trim()) {
    return '';
  }

  let output = '';
  
  if (config.value.outputFormat === 'iptables' || config.value.outputFormat === 'both') {
    output += generateIptablesRules();
  }
  
  if (config.value.outputFormat === 'firewalld' || config.value.outputFormat === 'both') {
    if (output) output += '\n\n';
    output += generateFirewalldRules();
  }
  
  return output;
});

// 计算规则数量
const ruleCount = computed(() => {
  if (!generatedRules.value) return 0;
  return generatedRules.value.split('\n').filter(line => line.trim() && line.startsWith('iptables')).length;
});

// 加载示例配置
const loadExample = (type: string) => {
  switch (type) {
    case 'web-server':
      config.value = {
        ...config.value,
        action: 'ACCEPT',
        protocol: 'tcp',
        chain: 'INPUT',
        destinationPorts: '80,443',
        outputFormat: 'iptables',
        includeComments: true
      };
      break;
    case 'ssh-access':
      config.value = {
        ...config.value,
        action: 'ACCEPT',
        protocol: 'tcp',
        chain: 'INPUT',
        destinationPorts: '22',
        sourceIPs: '192.168.1.0/24\n10.0.0.0/8',
        outputFormat: 'iptables',
        includeComments: true
      };
      break;
    case 'database':
      config.value = {
        ...config.value,
        action: 'ACCEPT',
        protocol: 'tcp',
        chain: 'INPUT',
        destinationPorts: '3306,5432,6379',
        sourceIPs: '192.168.1.0/24',
        outputFormat: 'iptables',
        includeComments: true
      };
      break;
    case 'ping':
      config.value = {
        ...config.value,
        action: 'ACCEPT',
        protocol: 'icmp',
        chain: 'INPUT',
        icmpType: 'echo-request',
        outputFormat: 'iptables',
        includeComments: true
      };
      break;
  }
};

// 生成 iptables 规则
const generateIptablesRules = () => {
  let rules = '';
  
  if (config.value.includeComments) {
    rules += '# iptables 防火墙规则\n';
    rules += `# 动作: ${config.value.action}\n`;
    rules += `# 协议: ${config.value.protocol}\n`;
    rules += `# 链: ${config.value.chain}\n\n`;
  }
  
  // 解析源IP和目标IP，支持范围格式
  const sourceIPRanges = parseIPRanges(config.value.sourceIPs);
  const destinationIPRanges = parseIPRanges(config.value.destinationIPs);
  
  // 如果没有指定源IP和目标IP，生成一条通用规则
  if (sourceIPRanges.length === 0 && destinationIPRanges.length === 0) {
    rules += generateSingleIptablesRule('', '', false, false);
    return rules;
  }
  
  // 生成规则，优先使用iprange模块
  if (sourceIPRanges.length > 0 && destinationIPRanges.length > 0) {
    // 源IP和目标IP都有
    for (const sourceRange of sourceIPRanges) {
      for (const destRange of destinationIPRanges) {
        rules += generateSingleIptablesRule(sourceRange, destRange, true, true);
      }
    }
  } else if (sourceIPRanges.length > 0) {
    // 只有源IP
    for (const sourceRange of sourceIPRanges) {
      rules += generateSingleIptablesRule(sourceRange, '', true, false);
    }
  } else if (destinationIPRanges.length > 0) {
    // 只有目标IP
    for (const destRange of destinationIPRanges) {
      rules += generateSingleIptablesRule('', destRange, false, true);
    }
  }
  
  return rules;
};

// 生成单条 iptables 规则
const generateSingleIptablesRule = (sourceIP: string, destIP: string, useSourceRange: boolean = false, useDestRange: boolean = false) => {
  let rule = `iptables -${config.value.insertPosition} ${config.value.chain}`;
  
  // 添加源IP
  if (sourceIP && sourceIP.trim().toLowerCase() !== 'any' && sourceIP.trim() !== '0.0.0.0/0') {
    if (useSourceRange && sourceIP.includes('-')) {
      // 使用iprange模块处理源IP范围
      rule += ` -m iprange --src-range ${sourceIP}`;
    } else {
      rule += ` -s ${sourceIP}`;
    }
  }
  
  // 添加目标IP
  if (destIP && destIP.trim().toLowerCase() !== 'any' && destIP.trim() !== '0.0.0.0/0') {
    if (useDestRange && destIP.includes('-')) {
      // 使用iprange模块处理目标IP范围
      rule += ` -m iprange --dst-range ${destIP}`;
    } else {
      rule += ` -d ${destIP}`;
    }
  }
  
  // 添加协议
  if (config.value.protocol !== 'all') {
    rule += ` -p ${config.value.protocol}`;
  }
  
  // 根据协议类型添加端口或ICMP类型
  if (config.value.protocol === 'icmp') {
    // ICMP协议使用类型和代码，不使用端口
    if (config.value.icmpType) {
      rule += ` --icmp-type ${config.value.icmpType}`;
    }
  } else if (config.value.protocol === 'tcp' || config.value.protocol === 'udp') {
    // TCP/UDP协议使用端口
    if (config.value.sourcePorts && config.value.sourcePorts.trim().toLowerCase() !== 'any' && config.value.sourcePorts.trim().toLowerCase() !== 'all') {
      if (config.value.sourcePorts.includes(',')) {
        rule += ` -m multiport --sport ${config.value.sourcePorts}`;
      } else {
        rule += ` --sport ${config.value.sourcePorts}`;
      }
    }
    
    if (config.value.destinationPorts && config.value.destinationPorts.trim().toLowerCase() !== 'any' && config.value.destinationPorts.trim().toLowerCase() !== 'all') {
      if (config.value.destinationPorts.includes(',')) {
        rule += ` -m multiport --dport ${config.value.destinationPorts}`;
      } else {
        rule += ` --dport ${config.value.destinationPorts}`;
      }
    }
  }
  
  // 添加接口
  if (config.value.interface) {
    rule += ` -i ${config.value.interface}`;
  }
  
  // 添加状态匹配
  if (config.value.state) {
    rule += ` -m state --state ${config.value.state}`;
  }
  
  // 添加动作
  rule += ` -j ${config.value.action}`;
  
  return rule + '\n';
};

// 生成 firewalld 规则
const generateFirewalldRules = () => {
  let rules = '';
  
  if (config.value.includeComments) {
    rules += '# firewalld 防火墙规则\n';
    rules += `# 动作: ${config.value.action}\n`;
    rules += `# 协议: ${config.value.protocol}\n\n`;
  }
  
  const sourceIPs = parseIPs(config.value.sourceIPs);
  const destinationPorts = config.value.destinationPorts;
  
  if (config.value.action === 'ACCEPT') {
    // 根据协议类型添加不同的规则
    if (config.value.protocol === 'icmp') {
      // ICMP协议
      if (config.value.icmpType) {
        rules += `firewall-cmd --zone=public --add-icmp-block-inversion --permanent\n`;
        rules += `firewall-cmd --zone=public --add-icmp-block=${config.value.icmpType} --permanent\n`;
      }
    } else if (config.value.protocol === 'tcp' || config.value.protocol === 'udp') {
      // TCP/UDP协议
      if (destinationPorts) {
        rules += `firewall-cmd --zone=public --add-port=${destinationPorts}/${config.value.protocol} --permanent\n`;
      }
    }
    
    // 添加源IP规则
    for (const sourceIP of sourceIPs) {
      rules += `firewall-cmd --zone=public --add-source=${sourceIP} --permanent\n`;
    }
  } else if (config.value.action === 'DROP' || config.value.action === 'REJECT') {
    // 拒绝规则
    for (const sourceIP of sourceIPs) {
      rules += `firewall-cmd --zone=drop --add-source=${sourceIP} --permanent\n`;
    }
  }
  
  rules += '\nfirewall-cmd --reload\n';
  
  return rules;
};

// 解析IP地址范围，支持iprange模块格式
const parseIPRanges = (ipText: string): string[] => {
  if (!ipText.trim()) return [];
  
  return ipText
    .split('\n')
    .map(line => line.trim())
    .filter(line => line && !line.startsWith('#'))
    .map(line => {
      // 支持三种格式：
      // 1. 单IP: 192.168.1.1
      // 2. CIDR: 192.168.1.0/24
      // 3. IP范围: 192.168.1.1-192.168.1.10
      return line;
    });
};

// 解析IP地址（旧版本，用于firewalld）
const parseIPs = (ipText: string): string[] => {
  if (!ipText.trim()) return [];
  
  return ipText
    .split('\n')
    .map(line => line.trim())
    .filter(line => line && !line.startsWith('#'))
    .map(line => {
      // 处理IP范围 (如: 192.168.1.1-192.168.1.10)
      if (line.includes('-') && !line.includes('/')) {
        const [start, end] = line.split('-');
        return expandIPRange(start.trim(), end.trim());
      }
      return [line];
    })
    .flat();
};

// 扩展IP范围
const expandIPRange = (startIP: string, endIP: string): string[] => {
  const ips: string[] = [];
  const start = ipToNumber(startIP);
  const end = ipToNumber(endIP);
  
  if (start && end && start <= end) {
    for (let i = start; i <= end; i++) {
      ips.push(numberToIP(i));
    }
  }
  
  return ips;
};

// IP地址转数字
const ipToNumber = (ip: string): number | null => {
  const parts = ip.split('.');
  if (parts.length !== 4) return null;
  
  let result = 0;
  for (let i = 0; i < 4; i++) {
    const part = parseInt(parts[i]);
    if (isNaN(part) || part < 0 || part > 255) return null;
    result = result * 256 + part;
  }
  return result;
};

// 数字转IP地址
const numberToIP = (num: number): string => {
  const parts = [];
  for (let i = 0; i < 4; i++) {
    parts.unshift(num % 256);
    num = Math.floor(num / 256);
  }
  return parts.join('.');
};

// 清空所有配置
const clearAll = () => {
  config.value = {
    action: 'ACCEPT',
    protocol: 'tcp',
    chain: 'INPUT',
    insertPosition: 'I',
    sourceIPs: '',
    destinationIPs: '',
    sourcePorts: '',
    destinationPorts: '',
    icmpType: '',
    interface: '',
    state: '',
    outputFormat: 'iptables',
    includeComments: true
  };
};

// 复制结果
const copyResult = async () => {
  if (generatedRules.value) {
    await copy(generatedRules.value);
  }
};

// 验证IP地址格式
const validateIP = (ip: string): boolean => {
  const trimmedIP = ip.trim().toLowerCase();
  
  // 检查特殊值
  if (trimmedIP === 'any' || trimmedIP === '0.0.0.0/0') {
    return true;
  }
  
  // 检查CIDR格式 (如: 192.168.1.0/24)
  if (trimmedIP.includes('/')) {
    const [ipPart, cidrPart] = trimmedIP.split('/');
    const cidr = parseInt(cidrPart);
    if (isNaN(cidr) || cidr < 0 || cidr > 32) return false;
    return validateSingleIP(ipPart);
  }
  
  // 检查IP范围格式 (如: 192.168.1.1-192.168.1.10)
  if (trimmedIP.includes('-')) {
    const [startIP, endIP] = trimmedIP.split('-');
    return validateSingleIP(startIP) && validateSingleIP(endIP);
  }
  
  // 检查单个IP地址
  return validateSingleIP(trimmedIP);
};

// 验证单个IP地址
const validateSingleIP = (ip: string): boolean => {
  const ipRegex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
  return ipRegex.test(ip);
};

// 验证端口格式
const validatePort = (port: string): boolean => {
  const trimmedPort = port.trim().toLowerCase();
  
  if (!trimmedPort) return true; // 空值视为有效（表示所有端口）
  
  // 检查特殊值
  if (trimmedPort === 'any' || trimmedPort === 'all') {
    return true;
  }
  
  // 检查端口范围 (如: 80-90)
  if (trimmedPort.includes('-')) {
    const [startPort, endPort] = trimmedPort.split('-');
    const start = parseInt(startPort);
    const end = parseInt(endPort);
    return !isNaN(start) && !isNaN(end) && start >= 1 && end <= 65535 && start <= end;
  }
  
  // 检查多个端口 (如: 80,443,8080)
  if (trimmedPort.includes(',')) {
    return trimmedPort.split(',').every(p => {
      const portNum = parseInt(p.trim());
      return !isNaN(portNum) && portNum >= 1 && portNum <= 65535;
    });
  }
  
  // 检查单个端口
  const portNum = parseInt(trimmedPort);
  return !isNaN(portNum) && portNum >= 1 && portNum <= 65535;
};

// 验证配置
const validateConfig = () => {
  const errors = {
    sourceIPs: [] as string[],
    destinationIPs: [] as string[],
    sourcePorts: [] as string[],
    destinationPorts: [] as string[]
  };
  
  // 验证源IP地址
  if (config.value.sourceIPs.trim()) {
    const sourceIPs = config.value.sourceIPs.split('\n').filter(ip => ip.trim());
    sourceIPs.forEach((ip, index) => {
      if (!validateIP(ip.trim())) {
        errors.sourceIPs.push(`第${index + 1}行: "${ip.trim()}" 不是有效的IP地址格式`);
      }
    });
  }
  
  // 验证目标IP地址
  if (config.value.destinationIPs.trim()) {
    const destinationIPs = config.value.destinationIPs.split('\n').filter(ip => ip.trim());
    destinationIPs.forEach((ip, index) => {
      if (!validateIP(ip.trim())) {
        errors.destinationIPs.push(`第${index + 1}行: "${ip.trim()}" 不是有效的IP地址格式`);
      }
    });
  }
  
  // 验证源端口
  if (config.value.sourcePorts.trim() && (config.value.protocol === 'tcp' || config.value.protocol === 'udp')) {
    if (!validatePort(config.value.sourcePorts)) {
      errors.sourcePorts.push('源端口格式无效，支持格式：80、80-90、80,443,8080、any（任意端口）');
    }
  }
  
  // 验证目标端口
  if (config.value.destinationPorts.trim() && (config.value.protocol === 'tcp' || config.value.protocol === 'udp')) {
    if (!validatePort(config.value.destinationPorts)) {
      errors.destinationPorts.push('目标端口格式无效，支持格式：80、80-90、80,443,8080、any（任意端口）');
    }
  }
  
  validationErrors.value = errors;
  return Object.values(errors).every(errorArray => errorArray.length === 0);
};

// 监听配置变化，实时验证
watch(() => [config.value.sourceIPs, config.value.destinationIPs, config.value.sourcePorts, config.value.destinationPorts, config.value.protocol], () => {
  validateConfig();
}, { deep: true });

// 下载结果
const downloadResult = () => {
  if (!generatedRules.value) return;
  
  const blob = new Blob([generatedRules.value], { type: 'text/plain' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = 'firewall-rules.sh';
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  URL.revokeObjectURL(url);
};
</script>

<style scoped>
.firewall-rule-generator {
  min-height: 100vh;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  padding: 2rem;
}

.main-workspace {
  max-width: 1600px;
  margin: 0 auto;
}

.workspace-grid {
  display: grid;
  grid-template-columns: 1.2fr 0.8fr;
  gap: 2rem;
  align-items: start;
}

.workspace-card {
  background: white;
  border-radius: 16px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
  overflow: hidden;
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.2);
}

.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1.5rem;
  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
  border-bottom: 1px solid #e1e5e9;
}

.card-title {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.title-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-radius: 10px;
  color: white;
}

.title-text h3 {
  margin: 0;
  font-size: 1.25rem;
  font-weight: 600;
  color: #2d3748;
}

.title-text p {
  margin: 0.25rem 0 0 0;
  font-size: 0.875rem;
  color: #718096;
}

.card-actions {
  display: flex;
  gap: 0.5rem;
}

.clear-btn {
  background: #fed7d7;
  border-color: #feb2b2;
  color: #c53030;
}

.clear-btn:hover {
  background: #feb2b2;
  border-color: #fc8181;
}

.card-content {
  padding: 1.5rem;
}

.config-section {
  margin-bottom: 2rem;
}

.config-section:last-child {
  margin-bottom: 0;
}

.section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.5rem;
}

.section-title {
  font-size: 1.1rem;
  font-weight: 600;
  color: #2d3748;
  margin: 0;
  padding-bottom: 0.5rem;
  border-bottom: 2px solid #e2e8f0;
}

.warning-badge {
  background: linear-gradient(135deg, #f56565 0%, #e53e3e 100%);
  color: white;
  padding: 0.25rem 0.5rem;
  border-radius: 6px;
  font-size: 0.75rem;
  font-weight: 600;
  box-shadow: 0 2px 4px rgba(245, 101, 101, 0.3);
}

.info-badge {
  background: linear-gradient(135deg, #4299e1 0%, #3182ce 100%);
  color: white;
  padding: 0.25rem 0.5rem;
  border-radius: 6px;
  font-size: 0.75rem;
  font-weight: 600;
  box-shadow: 0 2px 4px rgba(66, 153, 225, 0.3);
}

.warning-tip {
  background: linear-gradient(135deg, #fed7d7 0%, #feb2b2 100%);
  border: 1px solid #fc8181;
  border-radius: 8px;
  padding: 0.75rem;
  margin-bottom: 1rem;
  color: #c53030;
  font-size: 0.875rem;
  line-height: 1.4;
}

.info-tip {
  background: linear-gradient(135deg, #bee3f8 0%, #90cdf4 100%);
  border: 1px solid #63b3ed;
  border-radius: 8px;
  padding: 0.75rem;
  margin-bottom: 1rem;
  color: #2b6cb0;
  font-size: 0.875rem;
  line-height: 1.4;
}

.field-hint {
  font-size: 0.75rem;
  color: #718096;
  margin-top: 0.25rem;
  display: block;
}

/* 规则统计信息 */
.rules-stats {
  display: flex;
  gap: 1rem;
  margin-bottom: 1rem;
  padding: 0.75rem;
  background: linear-gradient(135deg, #f7fafc 0%, #edf2f7 100%);
  border-radius: 8px;
  border: 1px solid #e2e8f0;
}

.stat-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex: 1;
}

.stat-label {
  font-size: 0.75rem;
  color: #718096;
  margin-bottom: 0.25rem;
}

.stat-value {
  font-size: 1.1rem;
  font-weight: 600;
  color: #2d3748;
}

/* 规则输出区域 */
.rules-output-section {
  margin-bottom: 1.5rem;
}

.output-title {
  margin: 0;
  font-size: 1rem;
  font-weight: 600;
  color: #2d3748;
}

.output-badge {
  background: linear-gradient(135deg, #48bb78 0%, #38a169 100%);
  color: white;
  padding: 0.25rem 0.5rem;
  border-radius: 6px;
  font-size: 0.75rem;
  font-weight: 600;
}

/* 使用说明 */
.usage-guide {
  margin-bottom: 1.5rem;
  padding: 1rem;
  background: linear-gradient(135deg, #f0fff4 0%, #dcfce7 100%);
  border-radius: 8px;
  border: 1px solid #9ae6b4;
}

.guide-title {
  margin: 0 0 1rem 0;
  font-size: 1rem;
  font-weight: 600;
  color: #22543d;
}

.guide-content {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.guide-step {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.step-number {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  background: #48bb78;
  color: white;
  border-radius: 50%;
  font-size: 0.875rem;
  font-weight: 600;
}

.step-text {
  font-size: 0.875rem;
  color: #22543d;
}

/* 示例区域 */
.examples-section {
  margin-top: 1.5rem;
}

.examples-title {
  margin: 0 0 1rem 0;
  font-size: 1rem;
  font-weight: 600;
  color: #2d3748;
}

.examples-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
}

.example-card {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem;
  background: white;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.2s ease;
}

.example-card:hover {
  background: #f7fafc;
  border-color: #cbd5e0;
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.example-icon {
  font-size: 1.5rem;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-radius: 8px;
  color: white;
}

.example-content h6 {
  margin: 0 0 0.25rem 0;
  font-size: 0.875rem;
  font-weight: 600;
  color: #2d3748;
}

.example-content p {
  margin: 0;
  font-size: 0.75rem;
  color: #718096;
}

/* 验证错误样式 */
.validation-errors {
  margin-top: 0.5rem;
}

.error-item {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  margin-bottom: 0.25rem;
  padding: 0.5rem;
  background: #fed7d7;
  border: 1px solid #feb2b2;
  border-radius: 6px;
  color: #c53030;
  font-size: 0.875rem;
  line-height: 1.4;
}

.error-icon {
  font-size: 1rem;
  flex-shrink: 0;
  margin-top: 0.125rem;
}

.error-text {
  flex: 1;
}

/* 生成选项样式 */
.options-row {
  display: flex;
  gap: 2rem;
  align-items: center;
  padding: 1rem;
  background: linear-gradient(135deg, #f7fafc 0%, #edf2f7 100%);
  border-radius: 8px;
  border: 1px solid #e2e8f0;
}

.option-item {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  flex: 1;
}

.option-label {
  font-size: 0.875rem;
  font-weight: 600;
  color: #2d3748;
  margin: 0;
}

.config-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}

.config-output {
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
  font-size: 0.875rem;
  line-height: 1.5;
  background: #f7fafc;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
}

/* 响应式设计 */
@media (max-width: 1024px) {
  .workspace-grid {
    grid-template-columns: 1fr;
    gap: 1.5rem;
  }
  
  .config-grid {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 768px) {
  .firewall-rule-generator {
    padding: 1rem;
  }
  
  .page-title {
    font-size: 2rem;
  }
  
  .header-content {
    flex-direction: column;
    text-align: center;
  }
  
  .card-header {
    flex-direction: column;
    gap: 1rem;
    align-items: stretch;
  }
  
  .card-actions {
    justify-content: center;
  }
}
</style>